using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using System.IO;
using Ltf.Remoting.TeamFoundation;
using Ltf.MonitorLizard.Helpers;
using Ltf.Remoting.TFAccess;
using Ltf.MonitorLizard.Forms;
using Ltf.Remoting.RemoteEvents;
using Ltf.Remoting;
using Ltf.Remoting.Server;
using Ltf.Remoting.Commands;
using System.Diagnostics;
using Ltf.MonitorLizard.Controls.BufferedTreeView;
using Ltf.Remoting.Operations;

namespace Ltf.MonitorLizard
{
	[FormType(FormTypes.RepoBrowser)]

	public partial class TFProjectBrowser : Form
	{
		private Dictionary<string, TeamProject> teamProjects;
		private string selectedProjectPath = string.Empty;
		private VersionControlServer versionControlServer;
		private Ltf.MonitorLizard.Helpers.FileIcons fileIcons;

		private HistorySelector historySelector;

		private bool ignoreVersionChange = false;

		private ItemType itemType;
		private VersionSpec versionSpec;
		private bool isBranchTargetSelector = false;
		private string branchSourceLocalPath;
		private Workspace workspace;
		private bool hasItemView = false;

		private string lastSelectedItem = string.Empty;
		private string lastSelectedVersion = string.Empty;
		private ItemType lastSelectedItemType = ItemType.Folder;
		private int lastSelectedDeletionId = 0;

		private TreeNode lastSetNode = null;

		private TFServerConnection connection;

		private bool ignoreControlEvents = false;

		public TFProjectBrowser(string[] paths, LizardEventArgs args)
		{
			ignoreControlEvents = true;
			InitializeComponent();
			connection = ServerConnections.GetConnectionForPath(paths[0]);
			this.workspace = connection.GetWorkspace(paths[0]);

			this.projectPath = workspace.TryGetServerItemForLocalItem(paths[0]);
			// get the extended item
			ItemSpec[] iss = new ItemSpec[] { new ItemSpec(projectPath,RecursionType.None) };
			DeletedState ds = DeletedState.NonDeleted;
			if (ckbShowDeletedItems != null && ckbShowDeletedItems.Checked)
				ds = DeletedState.Any;
			ExtendedItem extItem = workspace.GetExtendedItems(iss, ds ,ItemType.Any)[0][0];

			// set the version, nb. use 0 (zero) for latest.
			ProjectVersion = extItem.VersionLatest==extItem.VersionLocal?0:extItem.VersionLocal;

			this.itemType = ItemType.Any;
			hasItemView = true;
			Initialise();
			btnOkay.Visible = false;
			btnCancel.Text = "&Close";
			ignoreControlEvents = false;
		}


		public TFProjectBrowser(string suggestedPath, bool isBranchTargetSelector, Workspace workspace)
			: this(suggestedPath, ItemType.Folder, workspace)
		{
			connection = ServerConnections.DefaultConnection;
			this.workspace = workspace;
			cmbVersion.Visible = false;
			this.Text = "Select Branch Target Path";
			isBranchTargetSelector = true;
			branchSourceLocalPath = suggestedPath;
		}


		//public TFProjectBrowser()
		//  : this(string.Empty, ItemType.Folder, null) { }

		//public TFProjectBrowser(string projectPath)
		//  : this(projectPath, ItemType.Folder, null) { }

		public TFProjectBrowser(string projectPath, Workspace workspace)
			: this(projectPath, ItemType.Folder, workspace) { }


		public TFProjectBrowser(string projectPath, ItemType itemType, Workspace workspace)
		{
			ignoreControlEvents = true;
			if (projectPath.StartsWith("$"))
				connection = ServerConnections.GetConnectionForServerPath(projectPath, workspace);
			else
				connection = ServerConnections.GetConnectionForPath(projectPath);
			this.workspace = workspace;
			InitializeComponent();
			this.ProjectPath = projectPath;
			this.itemType = itemType;
			Initialise();
			ignoreControlEvents = false;
		}

		public TFProjectBrowser(string projectPath, ItemType itemType, Workspace workspace, bool hasItemView)
		{
			ignoreControlEvents = true;
			if (projectPath.StartsWith("$"))
				connection = ServerConnections.GetConnectionForServerPath(projectPath, workspace);
			else
				connection = ServerConnections.GetConnectionForPath(projectPath);
			this.workspace = workspace;
			InitializeComponent();
			this.ProjectPath = projectPath;
			this.hasItemView = hasItemView;
			
			this.itemType = itemType;
			Initialise();
			ignoreControlEvents = false;
		}

		private void Initialise()
		{
			bool previousState = ignoreControlEvents;
			ignoreControlEvents = true;
			splitContainer1.Panel2Collapsed = !hasItemView;
			this.Width -= (hasItemView ? 0 : lvwItems.Width);
			fileIcons = new Ltf.MonitorLizard.Helpers.FileIcons(imlTreeImages);
			if (itemType == ItemType.Any)
				Width = (int)(Width * 1.6);
			sselConnection.Connection = connection;
			ShowProjects();
			ignoreControlEvents = previousState;
		}

		private void ShowProjects()
		{
			string name;
			tvwProject.Nodes.Clear();
			//int v = 0;
			//ProjectPath = projectPath;

			historySelector = new HistorySelector(cmbVersion, connection, workspace);
			historySelector.Path = projectPath;
		}

		private bool isIncludeDeletedItems = false;

		public bool IsIncludeDeletedItems
		{
			get { return isIncludeDeletedItems; }
			set { isIncludeDeletedItems = value; }
		}

		void tvwProject_AfterSelect(object sender, TreeViewEventArgs e)
		{
			if (ignoreControlEvents)
				return;
			using (new HourGlass(this))
			{
				tvwProject.BeginUpdate();
				if (tvwProject.SelectedNode != null)
				{
					selectedProjectPath = tvwProject.SelectedNode.Tag.ToString().Replace("...", "");
					lastSelectedItem = selectedProjectPath;
					lastSelectedItemType = ItemType.Folder;
					lastSelectedVersion = "0";
					int v = 0;
					int.TryParse(cmbVersion.Text, out v);
					lastSelectedVersion = v.ToString();
					LoadQuickHistory(selectedProjectPath, true);
					if (!ignoreVersionChange)
						LizardFileAccess.LoadVersions(connection, cmbVersion, selectedProjectPath);
					historySelector.Path = selectedProjectPath;
					if (hasItemView && !loading)
						LoadListItems(e.Node.Tag.ToString());
				}
				tvwProject.EndUpdate();
			}
		}

		public string ProjectPathName
		{
			get
			{
				string projectPathName;
				int v;
				LizardFileAccess.GetNameAndVersionFromPath(projectPath, out projectPathName, out v);
				return projectPathName;
			}
		}

		public TFServerConnection Connection
		{
			get { return connection; }
			set { connection = value; }
		}

		private string projectPath = string.Empty;

		public string ProjectPath
		{
			get { return projectPath; }
			set
			{
				int v = 0;
				string name = string.Empty;
				LizardFileAccess.GetNameAndVersionFromPath(value, out name, out v);
				projectPath = name;
				ProjectVersion = v;
			}
		}

		private int projectVersion;

		public int ProjectVersion
		{
			get { return projectVersion; }
			set 
			{
				projectVersion = value;
				if (projectVersion == 0)
				{
					versionSpec = VersionSpec.Latest;
					string vs = "Latest";
					if (!cmbVersion.Items.Contains(vs))
						cmbVersion.Items.Add(vs);
					cmbVersion.Text = vs;
				}
				else
				{
					versionSpec = new ChangesetVersionSpec(projectVersion);
					if (cmbVersion != null)
					{
						string vs = projectVersion.ToString();
						if (!cmbVersion.Items.Contains(vs))
							cmbVersion.Items.Add(vs);
						cmbVersion.Text = vs;
					}
				}
			}
		}

		public Item[] GetSelectedItems()
		{
			List<Item> items = new List<Item>();
			foreach (ListViewItem lvi in lvwItems.SelectedItems)
			{
				items.Add(lvi.Tag as Item);
			}

			return items.ToArray();
		}

		private void LoadProjectsCombo()
		{
			using (HourGlass hg = new HourGlass(this))
			{
				VersionControlServer vcServer = connection.VersionControlServer;
				TeamProject[] projects = vcServer.GetAllTeamProjects(true);
				cmbProjects.Items.Clear();
				teamProjects = new Dictionary<string, TeamProject>();
				cmbProjects.Items.Add("All");
				foreach (TeamProject tp in projects)
				{
					cmbProjects.Items.Add("$/" + tp.Name);
					teamProjects.Add("$/" + tp.Name, tp);
					if (projectPath.StartsWith("$/" + tp.Name))
						cmbProjects.SelectedIndex = cmbProjects.Items.Count - 1;
				}
				if (cmbProjects.SelectedIndex == -1)
				{
					cmbProjects.SelectedIndex = 0;
					if (!ignoreVersionChange)
						LizardFileAccess.LoadVersions(connection, cmbVersion, cmbProjects.SelectedItem.ToString(), projectVersion, 0);
				}
			}
		}

		private void cmbProjects_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (ignoreControlEvents)
				return;
			//		if (!loading)
			ReloadAllViews();
		}

		private void ReloadAllViews()
		{
			lastSetNode = null;
			string project = cmbProjects.SelectedItem.ToString();
			if (project == "All")
			{
				VersionControlServer vcServer = connection.VersionControlServer;
				TeamProject[] projects = vcServer.GetAllTeamProjects(true);
				tvwProject.Nodes.Clear();
				foreach (TeamProject tp in projects)
				{
					HiddenChildrenNode tn = new HiddenChildrenNode(tp.Name);
					tvwProject.Nodes.Add(tn);
					tn.ImageKey = "$project";
					tn.Tag = "..." + LizardFileAccess.SetPathVersionAndDeletionId(tp.ServerItem, GetCurrentChangesetId(), 0);
					//					tn.Tag = string.Format("...{0};c{1};d0", tp.ServerItem, GetCurrentChangesetId());
					tn.SelectedImageKey = "$project";
					TreeNode dummy = new HiddenChildrenNode("Loading...");
					tn.Nodes.Add(dummy);
					dummy.Tag = "***dummy";
					if (projectPath.StartsWith("$/" + tp.Name))
					{
						tvwProject.SelectedNode = tn;
						if (lastSetNode != null)
							tvwProject.SelectedNode = lastSetNode;
					}

				}
			}
			else if (teamProjects != null && teamProjects.ContainsKey(project))
			{
				bool previousState = ignoreVersionChange;
				ignoreVersionChange = true;
				LizardFileAccess.LoadVersions(connection, cmbVersion, project, projectVersion, 0);
				ignoreVersionChange = previousState;

				LoadProjectHierarchy(teamProjects[project]);
			}
			if (!currentViewedServerItem.StartsWith(project) && project != "All")
			{
				LoadListItems(project);
			}
		}


		private void LoadProjectHierarchy(TeamProject teamProject)
		{
			using (HourGlass hg = new HourGlass(this))
			{
				tvwProject.Nodes.Clear();
				TreeNode tn = new HiddenChildrenNode(teamProject.Name);
				tvwProject.Nodes.Add(tn);
				tn.Tag = "..." + LizardFileAccess.SetPathVersionAndDeletionId(teamProject.ServerItem, GetCurrentChangesetId(), 0);
				//				tn.Tag = string.Format("...{0};c{1};d0", teamProject.ServerItem, GetCurrentChangesetId());
				tn.ImageKey = "$project";
				tn.SelectedImageKey = "$project";
				versionControlServer = teamProject.VersionControlServer;
				tvwProject.SelectedNode = null;
				LoadItems(tn, teamProject.ServerItem);
				if (lastSetNode != null)
					tvwProject.SelectedNode = lastSetNode;
				if (tvwProject.SelectedNode == null && tvwProject.Nodes.Count > 0)
					tvwProject.SelectedNode = tvwProject.Nodes[0];

			}
		}

		bool loading = false;
		private void LoadItems(TreeNode treeNode, string path)
		{
			if (loading)
				return;
			loading = true;
			if (treeNode.Nodes.Count == 1 && treeNode.Nodes[0].Tag.ToString() == "***dummy")
				treeNode.Nodes.RemoveAt(0);
			if (versionControlServer == null)
				versionControlServer = connection.VersionControlServer;

			int changesetId;
			int deletionId;
			string serverItem;
			LizardFileAccess.GetNameAndVersionFromPath(path, out serverItem, out changesetId, out deletionId);

			ItemSet items = versionControlServer.GetItems(serverItem, versionSpec, RecursionType.OneLevel, DeletedState.Any, itemType);
			foreach (Item item in items.Items)
			{
				if (item.ServerItem != serverItem)
				{
					if (item.ItemType == ItemType.Folder || !hasItemView)
					{
						HiddenChildrenNode tn = new HiddenChildrenNode(Path.GetFileName(item.ServerItem));
						if (item.ItemType == ItemType.Folder)
						{
							tn.ImageKey = "$folder";
							tn.SelectedImageKey = "$openfolder";
							if (item.DeletionId != 0)
							{
								fileIcons.AddLtfStatusToImage("$deletedfolder", imlTreeImages.Images["$folder"], LizardOverLayStatus.Deleted);
								fileIcons.AddLtfStatusToImage("$deletedopenfolder", imlTreeImages.Images["$openfolder"], LizardOverLayStatus.Deleted);
								tn.ImageKey = "$deletedfolder";
								tn.SelectedImageKey = "$deletedopenfolder";
							}
							tn.Tag = "..." + LizardFileAccess.SetPathVersionAndDeletionId(item.ServerItem, item.ChangesetId, item.DeletionId);
							//						tn.Tag = string.Format("...{0};c{1};d{2}", item.ServerItem, item.ChangesetId, item.DeletionId);
							TreeNode dummy = new HiddenChildrenNode("Loading...");
							tn.Nodes.Add(dummy);
							dummy.Tag = "***dummy";
						}
						else
						{
							LizardOverLayStatus status = LizardOverLayStatus.None;
							if (workspace != null)
								status = LizardFileAccess.GetLizardFileInfo(workspace.TryGetLocalItemForServerItem(item.ServerItem)).OverlayType;
							if (item.DeletionId != 0)
								status = LizardOverLayStatus.Deleted;
							tn.ImageKey = fileIcons.LoadIconForFileExtensionAndLtfStatus(Path.GetExtension(item.ServerItem), status);
							//						tn.ImageKey = fileIcons.LoadIconForFileExtension(Path.GetExtension(item.ServerItem));
							tn.Tag = "..." + LizardFileAccess.SetPathVersionAndDeletionId(item.ServerItem, item.ChangesetId, item.DeletionId);
							// tn.Tag = string.Format("{0};c{1};d{2}", item.ServerItem, item.ChangesetId, item.DeletionId); ;
						}
						if (item.DeletionId != 0 || treeNode.ForeColor == System.Drawing.Color.Tomato)
						{
							tn.ForeColor = System.Drawing.Color.Tomato;
							tn.NodeFont = new System.Drawing.Font(tvwProject.Font, FontStyle.Strikeout);
							((HiddenChildrenNode)treeNode).AddSwitchableNode(tn);
						}
						else
						{
							treeNode.Nodes.Add(tn);

						}
						if (tn.ImageKey != "$folder")
							tn.SelectedImageKey = tn.ImageKey;
						if (projectPath.StartsWith(item.ServerItem)) // && projectPath != item.ServerItem)
						{
							loading = false;
							LoadItems(tn, item.ServerItem);
							loading = true;
							//		if (tvwProject.SelectedNode == null)
							if (lastSetNode == null || tn.Level >= lastSetNode.Level)
								lastSetNode = tn;
							tvwProject.SelectedNode = tn;
						}
						else if (projectPath == item.ServerItem)
						{
							if (lastSetNode == null || tn.Level >= lastSetNode.Level)
								lastSetNode = tn;
							tvwProject.SelectedNode = tn;
							LoadListItems(tn.Tag.ToString());
						}
					}
				}
			}
			loading = false;
		}

		private string currentViewedServerItem = string.Empty;
		/// <summary>
		/// Loads the list items.
		/// </summary>
		/// <param name="serverItem">The server item.</param>
		private void LoadListItems(string path)
		{
			if (path.StartsWith("..."))
				path = path.Substring(3);

			int changesetId = 0;
			int deletionId = 0;
			string serverItem;
			LizardFileAccess.GetNameAndVersionFromPath(path, out serverItem, out changesetId, out deletionId);


			currentViewedServerItem = serverItem;

			if (workspace != null)
			{
				string localFolder = workspace.TryGetLocalItemForServerItem(serverItem);
				if (localFolder != null)
				{
					Ltf.Remoting.Server.ServerFunctions sf = new Ltf.Remoting.Server.ServerFunctions();
					sf.ParseFolder(localFolder);
				}
			}
			if (versionControlServer == null)
				versionControlServer = connection.VersionControlServer;

			ItemSet items = versionControlServer.GetItems(serverItem, versionSpec, RecursionType.OneLevel, DeletedState.Any, itemType);
			ItemSpec ispec = new ItemSpec(serverItem, RecursionType.OneLevel);
			ExtendedItem[] extItems = new ExtendedItem[0];
			if (workspace != null)
				extItems = workspace.GetExtendedItems(new ItemSpec[] { ispec }, DeletedState.Any, ItemType.Any)[0];

			Dictionary<string, ExtendedItem> extItemsByServerItem = new Dictionary<string, ExtendedItem>();

			foreach (ExtendedItem extItem in extItems)
			{
				string key = extItem.SourceServerItem;
				if (extItem.DeletionId != 0)
					key = string.Format("{0} [{1}]", key, extItem.DeletionId);
				extItemsByServerItem.Add(key, extItem);
			}

			lvwItems.Items.Clear();
			lvwItems.SmallImageList = imlTreeImages;
			foreach (Item item in items.Items)
			{
				if (item.ServerItem != serverItem && (item.DeletionId == 0 || isIncludeDeletedItems))
				{
					string filename = workspace.TryGetLocalItemForServerItem(item.ServerItem);
					LizardFileInfo lfi = LizardFileAccess.GetLizardFileInfo(filename);
					string localVersion = lfi.LocalVersion.ToString();
					string localFile = null;
					if (extItemsByServerItem.ContainsKey(item.ServerItem))
					{
						localFile = extItemsByServerItem[item.ServerItem].LocalItem;
						localVersion = extItemsByServerItem[item.ServerItem].VersionLocal.ToString();
					}
					if (localVersion == "0")
						localVersion = "-";
					else if (localFile != null && !File.Exists(localFile) && !Directory.Exists(localFile))
						localVersion = "missing";
					string serverVersion = item.ChangesetId.ToString();

					ListViewItem lvi = new ListViewItem(new string[] { Path.GetFileName(item.ServerItem), lfi.ChangeType, serverVersion, localVersion });
					lvi.Tag = item;
					LizardOverLayStatus status = lfi.OverlayType;
					if (item.DeletionId != 0)
					{
						status = LizardOverLayStatus.Deleted;
						lvi.ForeColor = Color.Tomato;
						lvi.Font = new System.Drawing.Font(lvi.Font, FontStyle.Strikeout);
					}
					if (item.ItemType == ItemType.File)
						lvi.ImageKey = fileIcons.LoadIconForFileExtensionAndLtfStatus(Path.GetExtension(item.ServerItem), status);
					else
						lvi.ImageKey = "$folder";
					lvwItems.Items.Add(lvi);
				}
			}
		}

		private void btnOkay_Click(object sender, EventArgs e)
		{
			if (!isBranchTargetSelector)
			{
				this.DialogResult = DialogResult.OK;
				projectPath = selectedProjectPath;
				if (selectedProjectPath == string.Empty && tvwProject.SelectedNode != null)
					projectPath = tvwProject.SelectedNode.Tag.ToString().Replace("...", "");
				this.Close();
			}
			else
			{



			}
		}

		private void TFProjectBrowser_Shown(object sender, EventArgs e)
		{
			this.Refresh();
			this.Activate();
			ignoreControlEvents = true;
			LoadProjectsCombo();

			ReloadAllViews();

			ignoreControlEvents = false;
			cmbVersion.SelectedIndexChanged += new EventHandler(cmbVersion_SelectedIndexChanged);

			tvwProject.AfterSelect += new TreeViewEventHandler(tvwProject_AfterSelect);
			tvwProject.BeforeSelect += new TreeViewCancelEventHandler(tvwProject_BeforeSelect);
			tvwProject.BeforeExpand += new TreeViewCancelEventHandler(tvwProject_BeforeSelect);
		}

		void cmbVersion_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (ignoreControlEvents)
				return;
			if (ignoreVersionChange)
				return;
			ignoreVersionChange = true;
			string vs = cmbVersion.SelectedItem.ToString();
			int vi = 0;
			if (vs == "Latest")
				ProjectVersion = 0;
			else if (int.TryParse(vs, out vi))
				ProjectVersion = vi;
			else
				ProjectVersion = 0;
			if (tvwProject.SelectedNode != null)
				projectPath = tvwProject.SelectedNode.Tag.ToString().Replace("...", "");

			cmbProjects_SelectedIndexChanged(sender, e);
			ignoreVersionChange = false;

			//LoadProjectHierarchy(teamProjects[cmbProjects.SelectedItem.ToString()]);
			//if (!string.IsNullOrEmpty(currentViewedServerItem))
			//  LoadListItems(currentViewedServerItem);
		}


		void tvwProject_BeforeSelect(object sender, TreeViewCancelEventArgs e)
		{
			if (ignoreControlEvents)
				return;
			using (new HourGlass(this))
			{
				tvwProject.BeginUpdate();
				if (e.Node.Tag.ToString().StartsWith("...") && e.Node.Nodes.Count == 1
					&& e.Node.Nodes[0].Text == "Loading...")
				{
					LoadItems(e.Node, e.Node.Tag.ToString().Substring(3));
					if (!loading)
						e.Node.Expand();
					if (e.Node is HiddenChildrenNode)
					{
						if (isIncludeDeletedItems)
							((HiddenChildrenNode)e.Node).ShowAll();
						else
							((HiddenChildrenNode)e.Node).HideAll();
					}
				}
				tvwProject.EndUpdate();
			}
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			lvwItems.SelectedItems.Clear();

			Close();
		}

		private void lvwItems_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (ignoreControlEvents)
				return;
			if (lvwItems.SelectedItems.Count == 1)
			{
				Item item = lvwItems.SelectedItems[0].Tag as Item;
				if (item != null)
				{
					string path = LizardFileAccess.SetPathVersionAndDeletionId(item.ServerItem, item.ChangesetId, item.DeletionId);
					// string path = string.Format("{0};c{1};d{2}", item.ServerItem, item.ChangesetId, item.DeletionId);
					LoadQuickHistory(path, item.ItemType == ItemType.Folder);
				}

			}
		}

		private void LoadQuickHistory(string path, bool isFolder)
		{
			TFHistory history = new TFHistory(connection, path, workspace);
			history.GetHistory(GetCurrentChangesetId(), isFolder ? RecursionType.Full : RecursionType.None);
			lvwQuickHistory.Items.Clear();
			foreach (LizardChangeset c in history.Changesets)
			{
				ListViewItem lvi = new ListViewItem(
					new string[] { c.ChangesetId.ToString(), c.Comment, c.CreationDate.ToShortDateString(), c.Commiter });
				lvwQuickHistory.Items.Add(lvi);
				lvi.Tag = LizardFileAccess.SetPathVersion(path, c.ChangesetId);
				//			lvi.Tag = path + ";c" + c.ChangesetId;
			}
		}

		private MouseButtons lastMouseButton = MouseButtons.None;
		private void all_MouseDown(object sender, MouseEventArgs e)
		{
			lastMouseButton = e.Button;
		}

		private void tvwProject_Click(object sender, EventArgs e)
		{
			if (lastMouseButton == MouseButtons.Right)
			{
				MouseEventArgs me = (MouseEventArgs)e;
				TreeNode tn = tvwProject.HitTest(me.Location).Node;
				if (tn != null)
				{
					tvwProject.SelectedNode = tn;
					string serverItem = tvwProject.SelectedNode.Tag as string;
					if (serverItem != null)
					{
						if (serverItem.StartsWith("..."))
							serverItem = serverItem.Substring(3);
						string path = serverItem;

						int v;
						int deletionId;
						string name;
						LizardFileAccess.GetNameAndVersionFromPath(path, out name, out v, out deletionId);

						getToolStripMenuItem1.Visible = (deletionId == 0);
						undeleteToolStripMenuItem1.Visible = (deletionId != 0);
						undeleteToolStripMenuItem1.Tag = path;
						ContextMenus.LoadDiffMenu(cmsFolders, path, "Compare with ", connection, workspace);
						cmsFolders.Show(tvwProject, tvwProject.PointToClient(MousePosition));
					}
				}
			}
		}

		private void lvwQuickHistory_Click(object sender, EventArgs e)
		{
			if (lastMouseButton == MouseButtons.Right)
			{
				if (lvwQuickHistory.SelectedItems.Count == 1)
				{
					string path = lvwQuickHistory.SelectedItems[0].Tag.ToString();
					viewToolStripMenuItem.Visible = (lastSelectedItemType == ItemType.File);
					lastSelectedVersion = lvwQuickHistory.SelectedItems[0].Text;
					ContextMenus.LoadDiffMenu(cmsItems, path, "Compare with ", connection, workspace);
					cmsItems.Show(lvwQuickHistory, lvwQuickHistory.PointToClient(MousePosition));
				}
				else if (lvwQuickHistory.SelectedItems.Count == 2)
				{
					cmsTwoSelectedDiff.Show(lvwQuickHistory, lvwQuickHistory.PointToClient(MousePosition));
				}

			}
		}

		private void lvwItems_Click(object sender, EventArgs e)
		{
			Item item = null;
			if (lvwItems.SelectedItems.Count == 1)
			{
				item = lvwItems.SelectedItems[0].Tag as Item;
				lastSelectedItem = item.ServerItem; ;
				lastSelectedVersion = item.ChangesetId.ToString();
				lastSelectedItemType = item.ItemType;
				lastSelectedDeletionId = item.DeletionId;
			}
			if (lastMouseButton == MouseButtons.Right && item != null && lvwItems.SelectedItems.Count == 1)
			{
				string path = LizardFileAccess.SetPathVersionAndDeletionId(item.ServerItem, item.ChangesetId, item.DeletionId);
				//				string path = string.Format("{0};c{1};d{2}", item.ServerItem, item.ChangesetId, item.DeletionId.ToString());
				viewToolStripMenuItem.Visible = (item.ItemType == ItemType.File);

				getToolStripMenuItem.Visible = (item.DeletionId == 0);
				undeleteToolStripMenuItem.Visible = (item.DeletionId != 0);
				undeleteToolStripMenuItem.Tag = path;

				ContextMenus.LoadDiffMenu(cmsItems, path, "Compare with ", connection, workspace);
				propertiesToolStripMenuItem.Visible = (workspace.TryGetLocalItemForServerItem(item.ServerItem) != null);
				cmsItems.Show(lvwItems, lvwItems.PointToClient(MousePosition));

			}
			else if (lastMouseButton == MouseButtons.Right && lvwItems.SelectedItems.Count == 2)
			{
				cmsTwoSelectedDiff.Show(lvwItems, lvwItems.PointToClient(MousePosition));
			}
		}

		private void viewToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (lastSelectedItem != null && lastSelectedVersion != null)
			{
				int version = LizardFileAccess.GetChangesetIdFromVersionText(lastSelectedVersion);
				ViewItem(lastSelectedItem, version, lastSelectedDeletionId);
			}
		}

		private void ViewItem(string item, int version, int deletionId)
		{
			try
			{
				Process edit = new Process();

				string path1 = LizardFileAccess.GetFilePath(connection, item, version, deletionId, string.Empty);

				string args = "\"" + path1 + "\"";
				ProcessStartInfo psi = new ProcessStartInfo(connection.Settings.EditTool, args);
				psi.UseShellExecute = false;
				edit.StartInfo = psi;
				edit.StartInfo.CreateNoWindow = false;
				edit.Start();
			}
			catch
			{
				MessageBox.Show("Could not launch specified editor.", "LizardTF Edit/View");
			}
		}

		private void historyToolStripMenuItem_Click(object sender, EventArgs e)
		{
			HistorySelector hs = new HistorySelector(lastSelectedItem, connection, workspace);
			hs.Show();
			hs.Activate();
		}

		private void lvwItems_DoubleClick(object sender, EventArgs e)
		{
			Item item = null;
			if (lvwItems.SelectedItems.Count == 1)
			{
				item = lvwItems.SelectedItems[0].Tag as Item;
				if (item.ItemType == ItemType.Folder)
				{
					foreach (TreeNode tn in tvwProject.SelectedNode.Nodes)
					{
						if (tn.Text == Path.GetFileName(item.ServerItem))
						{
							tvwProject.SelectedNode = tn;
							tn.Expand();
						}
					}
				}
			}
		}

		private void getToolStripMenuItem1_Click(object sender, EventArgs e)
		{
			string itemName;
			int v;
			LizardFileAccess.GetNameAndVersionFromPath(lastSelectedItem, out itemName, out v);

			string path = workspace.TryGetLocalItemForServerItem(itemName);
			TFGetOptions tfgo = new TFGetOptions(workspace, lastSelectedItem, int.Parse(lastSelectedVersion), path);
			tfgo.ShowDialog();
		}

		private void propertiesToolStripMenuItem_Click(object sender, EventArgs e)
		{
			string path = workspace.TryGetLocalItemForServerItem(lastSelectedItem);
			if (path != null)
				FilePropertiesLauncher.ShowProperties(path.Replace("\"", ""), this.Handle);

		}

		private void ckbShowDeletedItems_CheckedChanged(object sender, EventArgs e)
		{
			isIncludeDeletedItems = ckbShowDeletedItems.Checked;
			if (tvwProject.SelectedNode != null)
			{
				string serverItem = tvwProject.SelectedNode.Tag.ToString();
				LoadListItems(serverItem);
			}
			foreach (TreeNode node in tvwProject.Nodes)
			{
				if (node is HiddenChildrenNode)
				{
					if (isIncludeDeletedItems)
						((HiddenChildrenNode)node).ShowAll();
					else
						((HiddenChildrenNode)node).HideAll();
				}
			}
		}

		private void showDifferencesToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (lvwItems.SelectedItems.Count == 2)
			{
				Item item1 = lvwItems.SelectedItems[0].Tag as Item;
				Item item2 = lvwItems.SelectedItems[1].Tag as Item;
				string version = string.Empty;
				int v = 0;
				string path1 = item1.ServerItem;
				string path2 = item2.ServerItem;

				if (int.TryParse(cmbVersion.Text, out v))
				{
					path1 = LizardFileAccess.SetPathVersion(path1, v);
					path2 = LizardFileAccess.SetPathVersion(path2, v);
				}

				TwoWayDiff twd = new TwoWayDiff(path1, path2, workspace, workspace);
				twd.ShowDialog();
			}
		}

		public VersionSpec GetCurrentVersionSpec()
		{
			int v = 0;
			int.TryParse(cmbVersion.Text, out v);
			if (v == 0)
				return VersionSpec.Latest;
			else
				return new ChangesetVersionSpec(v);

		}

		public int GetCurrentChangesetId()
		{
			int v = 0;
			int.TryParse(cmbVersion.Text, out v);
			return v;
		}

		private void undeleteToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (((ToolStripMenuItem)sender).Tag is string)
			{
				string path = ((ToolStripMenuItem)sender).Tag.ToString();
				int v;
				int deletionId;
				string name;
				LizardFileAccess.GetNameAndVersionFromPath(path, out name, out v, out deletionId);

				WorkspaceOperators wso = new WorkspaceOperators(connection, workspace);
				try
				{
					wso.PendUndelete(name, deletionId);
				}
				catch (Exception ex)
				{
					MessageBox.Show(string.Format("Undelete operation failed with the following message:\r\n{0}", ex.Message),
						"Undelete Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}

			}
		}

		private void sselConnection_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (ignoreControlEvents)
				return;
			connection = sselConnection.Connection;
			workspace = connection.GetWorkspace(connection.Settings.DefaultWorkingPath);
			ShowProjects();
			LoadProjectsCombo();
		}

	}
}